# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.auth.models import User
from lr.work.models import Work
import datetime


class BankException(Exception):
    """ Исключение, генерируемое при банковской операции """
    
    
    COMMON_ERR = 0
    NOT_ENOUGH_MONEY_ERR = 1
    
    def __init__(self, error_code, *args, **kwargs):
        self.error_code = error_code
        super(BankException, self).__init__(*args, **kwargs)



class BankManager(models.Manager):
    """ Менеджер создания нового банка """
    
    def create_bank(self, user):
        """ Создать новый банк """
        new_bank = self.create(user=user, cash=0)
        return new_bank



class TransactionManager(models.Manager):
    """ Менеджер создания новой транзакции """
    
    def create_transaction(self, cash, detail, sender=None, recipient=None, work=None):
        """ Создать новую транзакцию """
        if not sender and not recipient:
            raise BankException(BankException.COMMON_ERR, u'Cannot create transaction, that has no sender and recipient.')
        
        if cash <= 0:
            raise BankException(BankException.COMMON_ERR, u'Transaction must have a nonzero positive value.')
        
        if sender and recipient and sender.id == recipient.id:
            raise BankException(BankException.COMMON_ERR, u'Cannot transact from user to himself.')
        
        if sender:
            # Проверить, есть ли у отправителя указанная сумма,
            # если есть, то списать ее с отправителя
            bank = Bank.objects.get(user=sender)
            if bank.cash < cash:
                raise BankException(BankException.NOT_ENOUGH_MONEY_ERR, u'Sender does not have enough money.')
            else:
                bank.cash = bank.cash - cash;
                bank.save()
        
        if recipient:
            # Начислить указанную сумму получателю
            bank = Bank.objects.get(user=recipient)
            bank.cash = bank.cash + cash
            bank.save()
        
        new_transaction = self.create(cash=cash, sender=sender, recipient=recipient, detail=detail,
                                      time=datetime.datetime.now(), work=work)
        return new_transaction



class Bank(models.Model):
    """ Банк пользователя """
    user = models.OneToOneField(User, related_name='bank_user', verbose_name=u'Пользователь', primary_key=True)
    cash = models.DecimalField(max_digits=15, decimal_places=2, default=0, verbose_name=u'Наличность')
    
    objects = BankManager()
    
    
    class Meta:
        verbose_name = u'Банк'
        verbose_name_plural = u'Банки'
    
    
    def __unicode__(self):
        """ Имя поля в админке """
        return self.user.username



class Transaction(models.Model):
    """ Банковская танзакция """
    cash = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name=u'Сумма')
    sender = models.ForeignKey(User, blank=True, null=True, verbose_name=u'Отправитель', related_name='transaction_sender')
    recipient = models.ForeignKey(User, blank=True, null=True, verbose_name=u'Получатель', related_name='transaction_recipient')
    detail = models.CharField(max_length=127, verbose_name=u'Доп. информация')
    time = models.DateTimeField(verbose_name=u'Дата')
    work = models.ForeignKey(Work, blank=True, null=True, verbose_name=u'Произведение', related_name='transaction_work')
    
    objects = TransactionManager()
    
    
    class Meta:
        verbose_name = u'Транзакция'
        verbose_name_plural = u'Транзакции'
    
    
    def __unicode__(self):
        """ Имя поля в админке """
        if self.sender:
            sndr = self.sender.username
        else:
            sndr = 'CASH'
        if self.recipient:
            rcp = self.recipient.username
        else:
            rcp = 'CASH'
        return '%s -> %s' % (sndr, rcp)
    